//---------------------------------------------------------------------------
#include "stdafx.h"
//---------------------------------------------------------------------------
#include "VBO.h"

#define BUFFER_OFFSET(i) ((char*)0 + (i))

const VBOAttribute& VBOAttributes::getAttribute(unsigned int i) const { return m_attributes[i]; }
VBOAttribute& VBOAttributes::getAttribute(unsigned int i) { return m_attributes[i]; }
unsigned int VBOAttributes::getNumAttributes() const { return m_num_attributes;  }
unsigned int VBOAttributes::getStride() const { return m_stride;  }

void VBOAttributes::setAttributes(VBOAttribute* attributes, unsigned int N) {
	m_num_attributes = N;
	m_attributes = attributes;

	m_stride = 0;
	for (uint i = 0; i < m_num_attributes; i++) {
		VBOAttribute& att = attributes[i];
		att.offset = BUFFER_OFFSET(m_stride);
		m_stride += att.size * sizeof(att.type);
	}
	int x = 2;
}


BufferObject::BufferObject(GLenum target, GLenum usage) : m_buffer(0), m_target(target), m_usage(usage) { }

BufferObject::~BufferObject() {
	if (m_buffer != 0) glDeleteBuffers(1, &m_buffer);
}

void BufferObject::create() {
	glGenBuffers(1, &m_buffer);
	bind();
}

void BufferObject::bind() const {
	glBindBuffer(m_target, m_buffer);
}

void BufferObject::bufferData(GLuint length, const void* ptr) {
	bind();

	glBufferData(m_target, length, ptr, m_usage);
}

int BufferObject::getSize() {
	bind();

	GLint buffer_size = -1;
	glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &buffer_size);
	return buffer_size;
}

ElementBuffer::ElementBuffer(GLenum usage) : BufferObject(GL_ELEMENT_ARRAY_BUFFER, usage) {
}


void RenderBuffer(GLenum mode, const BufferObject& buffer, const VBOAttributes& attributes, const BufferObject& elements, const ElementAttributes element_attributes) {
	buffer.bind();
	elements.bind();

	for (uint i = 0; i < attributes.getNumAttributes(); i++) {
		const VBOAttribute &att = attributes.getAttribute(i);
		glEnableVertexAttribArray(att.index);
		glVertexAttribPointer(att.index, att.size, att.type, att.normalize, attributes.getStride(), att.offset);
	}



	glDrawElements(mode, element_attributes.getNumIndices(), element_attributes.getIndexType(), BUFFER_OFFSET(0));


	for (uint i = 0; i < attributes.getNumAttributes(); i++) {
		glDisableVertexAttribArray(attributes.getAttribute(i).index);
	}
}